package org.example.pattern.chain.factory;

import org.example.pattern.chain.dao.ChainConfigManager;
import org.example.pattern.chain.dao.ChainConfigManagerImpl;
import org.example.pattern.chain.handler.GatewayHandler;
import org.example.pattern.chain.model.ChainConfig;

import java.lang.reflect.InvocationTargetException;

/**
 * beyond u self and trust u self.
 *
 * @Author: lbc
 * @Date: 2023-05-12 10:54
 * @email: 594599620@qq.com
 * @Description: oh my god！ niu bi...
 */
public class GatewayHandlerEnumFactory {

    private static ChainConfigManager configManager = new ChainConfigManagerImpl();

    // 提供静态方法，获取第一个handler
    public static GatewayHandler getFirstGatewayHandler() {

        ChainConfig firstChainConfig = configManager.getFirstChainConfig();
        GatewayHandler firstGatewayHandler = newGatewayHandler(firstChainConfig);
        if (firstGatewayHandler == null) {
            return null;
        }

        ChainConfig tempChainConfig = firstChainConfig;
        Integer nextHandlerId = null;
        GatewayHandler tempGatewayHandler = firstGatewayHandler;
        // 迭代遍历所有handler，以及将它们链接起来
        while ((nextHandlerId = tempChainConfig.getNextHandlerId()) != null) {
            ChainConfig gatewayEntity = configManager.getChainConfig(nextHandlerId);
            GatewayHandler gatewayHandler = newGatewayHandler(gatewayEntity);
            tempGatewayHandler.setNext(gatewayHandler);
            tempGatewayHandler = gatewayHandler;
            tempChainConfig = gatewayEntity;
        }
        // 返回第一个handler
        return firstGatewayHandler;
    }

    /**
     * 反射实体化具体的处理者
     *
     * @param firstGatewayEntity
     * @return
     */
    private static GatewayHandler newGatewayHandler(ChainConfig firstGatewayEntity) {
        // 获取全限定类名
        String className = firstGatewayEntity.getReflectPackageInfo();
        try {
            // 根据全限定类名，加载并初始化该类，即会初始化该类的静态段
            Class<?> clazz = Class.forName(className);
            return (GatewayHandler) clazz.getConstructor().newInstance();
        } catch (ClassNotFoundException | InvocationTargetException | NoSuchMethodException | InstantiationException | IllegalAccessException e) {
            e.printStackTrace();
            System.out.println(e.getMessage());
        }
        return null;
    }


}
